
package pms.dao;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;


import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import pms.dto.BewDatRaumPerson;
import pms.dto.BewDatPersonDTO;
import pms.om.Raum;
import pms.om.BewDat;
import pms.om.Person;


/**
 * @author josef@dr-schneeberger.de
 */
public class BewDatDao extends HibernateDaoSupport {
	SimpleDateFormat deutschesDatumsFormat = new SimpleDateFormat("dd.MM.yyyy hh:mm");

	/**
	 * <p>returns all BewDat objects, which are not yet termiated, i.e. which have a tStampGeht property == null.
	 * All the results are returned as BewDatPersonenDTO objects.</p>
	 * <p>In order to access lazy loaded properties, a HibernateCallback is used.</p>
	 * @return A sorted set of BewDatPersonenDTO objects
	 * @see http://static.springframework.org/spring/docs/2.5.x/reference/orm.html#orm-hibernate-template
	 */
	@SuppressWarnings("unchecked")
	public Set<BewDatRaumPerson> findNichtBeendetDTO() {
		HibernateTemplate template = getHibernateTemplate();
		return (Set<BewDatRaumPerson>) template.execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria criteria = session.createCriteria(BewDat.class);
				criteria.add(Restrictions.isNull("tStampGeht"));
				List<BewDat> alleBewDat = criteria.list();
				return createDtoSet(alleBewDat);
			}
		});
	}

	/**
	 * <p>returns all BewDat objects as BewDatPersonenDTO objects.</p>
	 * <p>In order to access lazy loaded properties of those, a HibernateCallback is used.</p>
	 * @return A sorted set of BewDatPersonenDTO objects
	 * @see http://static.springframework.org/spring/docs/2.5.x/reference/orm.html#orm-hibernate-template
	 */
	@SuppressWarnings("unchecked")
	public Set<BewDatPersonDTO> findAllDTO() {
		HibernateTemplate template = getHibernateTemplate();
		return (Set<BewDatPersonDTO>) template.execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria criteria = session.createCriteria(BewDat.class);
				List<BewDat> alleBewDat = criteria.list();
				return createDtoSet(alleBewDat);
			}
		});
	}

	/**
	 * Private utility function
	 * @param bewdaten a List of persistent BewDat objects
	 * @return a Set of BewDatPersonenDTO objects
	 */
	private Set<BewDatPersonDTO> createDtoSet(List<BewDat> bewdaten) {
		Set<BewDatPersonDTO> results = new TreeSet<BewDatPersonDTO>();
		for (BewDat f : bewdaten) {
			Date a = f.gettStampGeht();
			results.add(new BewDatPersonDTO(f.gettStampKommt(), 
					f.getId(), 
					f.getRaum().getName(),
					deutschesDatumsFormat.format(f.gettStampKommt()),
					(a == null ? "" : deutschesDatumsFormat.format(a)),
					mannschaftToString(f.getAnwPerson())));
		}
		return results;
	}

	/**
	 * Private utility function
	 * @param AnwPersonSet a Set of Person objects
	 * @return a String of the names of those Person objects
	 */
	private String mannschaftToString(Set<Person> AnwPersonSet) {
		String mannschaft = "";
		String trenner = "";
		for (Person AnwPerson : AnwPersonSet) {
			mannschaft = mannschaft + trenner + AnwPerson.getVorname() + " "
					+ AnwPerson.getNachname();
			trenner = ", ";
		}
		return mannschaft;
	}

	/**
	 * @return all BewDat objects in the database.
	 */
	@SuppressWarnings("unchecked")
	public List<BewDat> findAll() {
		HibernateTemplate template = getHibernateTemplate();
		List alleBewDat = template.loadAll(BewDat.class);
		return (List<BewDat>) alleBewDat;
	}

	/**
	 *  Raum id and a set of Person ids.
	 * @param raumId
	 * @param personenIds
	 */
	public void beginne(int raumId, Set<Integer> personenIds) {
		HibernateTemplate template = getHibernateTemplate();
		Raum b = (Raum) template.get(Raum.class, raumId);
		Set<Person> AnwPerson = new HashSet<Person>();
		for(Integer personId : personenIds) {
			AnwPerson.add((Person) template.get(Person.class, personId));
		}
		BewDat f = new BewDat();
		f.setRaum(b);
		f.setAnwPerson(AnwPerson);
		template.saveOrUpdate(f);
	}

	/**
	 * Ends a trip by adding an tStampGeht date.
	 * @param id
	 */
	public void beende(int id) {
		HibernateTemplate template = getHibernateTemplate();
		BewDat f = (BewDat) template.get(BewDat.class, id);
		f.settStampGeht(new Date());
		template.saveOrUpdate(f);
	}

	/**
	 * <p>returns all BewDat objects as BewDatRaumPersonDTO objects.</p>
	 * <p>In order to access lazy loaded properties of those, a HibernateCallback is used.</p>
	 * @return A sorted set of BewDatPersonenDTO objects
	 * @see http://static.springframework.org/spring/docs/2.5.x/reference/orm.html#orm-hibernate-template
	 */
	@SuppressWarnings("unchecked")
	public List<BewDatRaumPerson> findAllVoll() {
		HibernateTemplate template = getHibernateTemplate();
		return (List<BewDatRaumPerson>) template.execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Criteria criteria = session.createCriteria(BewDat.class);
				List<BewDat> alleBewDat = criteria.list();
				List<BewDatRaumPerson> liste = new LinkedList<BewDatRaumPerson>();
				for (BewDat f : alleBewDat) {
					Set<Person> AnwPerson = f.getAnwPerson();
					for (Person p : AnwPerson) {
						BewDatRaumPerson fbpDto = new BewDatRaumPerson(f, p);
						liste.add(fbpDto);
					}
				}
				return liste;
			}
		});
	}

}

